﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

using Rabbit = RabbitMQ.Client;

namespace HYService.RabbitMQ
{
    public partial class RabbitHub
    {
        static readonly string X_DELAYED_TYPE = "x-delayed-type";
        static readonly string X_DELAYED_MESSAGE = "x-delayed-message";

        /// <summary>
        /// 声明交换机和队列并通过路由键将二者绑定
        /// </summary>
        /// <param name="exchange">交换机名称</param>
        /// <param name="type">交换机类型</param>
        /// <param name="queues">队列名称集合</param>
        /// <param name="routingKey">路由键(如果交换机类型是Fanout或Direct，此字段可以为空)</param>
        /// <param name="deferred">是否声明延迟队列</param>
        public static void Setup(string exchange, ExchangeType type, IEnumerable<string> queues, string routingKey = "", bool deferred = false)
        {
            try
            {
                string exchangeType = string.Empty;
                switch (type)
                {
                    case ExchangeType.Direct:
                        exchangeType = Rabbit.ExchangeType.Direct;
                        break;
                    case ExchangeType.Fanout:
                        exchangeType = Rabbit.ExchangeType.Fanout;
                        break;
                    case ExchangeType.Topic:
                        exchangeType = Rabbit.ExchangeType.Topic;
                        break;
                    default:
                        throw new Exception("请使用有效的交换机类型");
                }

                using (Rabbit.IConnection connection = RabbitBus.CreateConnection())
                {
                    var channel = connection.CreateModel();
                    if (!deferred)
                    {
                        channel.ExchangeDeclare(exchange, exchangeType, true, false, null);
                    }
                    else
                    {
                        var args = new Dictionary<string, object>();
                        args.Add(X_DELAYED_TYPE, exchangeType);
                        channel.ExchangeDeclare(exchange, X_DELAYED_MESSAGE, true, false, args);
                    }

                    foreach (var queue in queues)
                    {
                        channel.QueueDeclare(queue, true, false, false, null);
                        channel.QueueBind(queue, exchange, routingKey);
                    }
                }
            }
            catch
            {

            }
        }

        /// <summary>
        /// 声明一个广播类型的交换机和一个队列并通过路由键将二者绑定
        /// </summary>
        /// <param name="exchange">交换机名称</param>
        /// <param name="type">交换机类型</param>
        /// <param name="queues">队列名称集合</param>
        /// <param name="routingKey">路由键(如果交换机类型是Fanout或Direct，此字段可以为空)</param>
        /// <param name="deferred">是否声明延迟队列</param>
        public static void Setup(string exchange, ExchangeType type, string queue, string routingKey = "", bool deferred = false)
        {
            try
            {
                string exchangeType = string.Empty;
                switch (type)
                {
                    case ExchangeType.Direct:
                        exchangeType = Rabbit.ExchangeType.Direct;
                        break;
                    case ExchangeType.Fanout:
                        exchangeType = Rabbit.ExchangeType.Fanout;
                        break;
                    case ExchangeType.Topic:
                        exchangeType = Rabbit.ExchangeType.Topic;
                        break;
                    default:
                        throw new Exception("请使用有效的交换机类型");
                }

                using (Rabbit.IConnection connection = RabbitBus.CreateConnection())
                {
                    var channel = connection.CreateModel();
                    if (!deferred)
                    {
                        channel.ExchangeDeclare(exchange, exchangeType, true, false, null);
                    }
                    else
                    {
                        var args = new Dictionary<string, object>();
                        args.Add(X_DELAYED_TYPE, exchangeType);
                        channel.ExchangeDeclare(exchange, X_DELAYED_MESSAGE, true, false, args);
                    }

                    channel.QueueDeclare(queue, true, false, false, null);
                    channel.QueueBind(queue, exchange, routingKey);
                }
            }
            catch
            {

            }
        }
    }
}
